﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Is.Ex;
using Should.Fluent;

namespace Is.Test
{
    [TestClass]
    public class ContainsListExtensionsExTest
    {
        [TestMethod]
        public void Test_Contains()
        {
            string nullstring = null;

            List<string> strings = null;
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Zero());
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().One());
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Exactly(0));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Exactly(1));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().AtLeast(1));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().AtLeast(0));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().AtLeast(2));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().NoMoreThan(1));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().NoMoreThan(2));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().NoMoreThan(0));


            strings = new List<string>();
            strings.Contains().Zero().Should().Be.True();
            strings.Contains().One().Should().Be.False();
            strings.Contains().Exactly(0).Should().Be.True();
            strings.Contains().Exactly(1).Should().Be.False();
            strings.Contains().AtLeast(1).Should().Be.False();
            strings.Contains().AtLeast(0).Should().Be.True();
            strings.Contains().AtLeast(2).Should().Be.False();
            strings.Contains().NoMoreThan(1).Should().Be.True();
            strings.Contains().NoMoreThan(2).Should().Be.True();
            strings.Contains().NoMoreThan(0).Should().Be.True();

            strings = new List<string>() { "alma" };
            strings.Contains().Zero().Should().Be.False();
            strings.Contains().One().Should().Be.True();
            strings.Contains().Exactly(1).Should().Be.True();
            strings.Contains().Exactly(2).Should().Be.False();
            strings.Contains().AtLeast(1).Should().Be.True();
            strings.Contains().AtLeast(0).Should().Be.True();
            strings.Contains().AtLeast(2).Should().Be.False();
            strings.Contains().NoMoreThan(1).Should().Be.True();
            strings.Contains().NoMoreThan(2).Should().Be.True();
            strings.Contains().NoMoreThan(0).Should().Be.False();

            strings = null;
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Any(s => s == "alma"));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Item("alma"));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().One(s => s == "alma"));
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().One("alma"));
            
            strings = new List<string>();
            strings.Contains().Any(s => s == "alma").Should().Be.False();
            strings.Contains().Any(s => s.Is().StartsWith("al")).Should().Be.False();
            strings.Contains().Any(s => s == "cser").Should().Be.False();
            strings.Contains().Any(s => s == null).Should().Be.False();
            strings.Contains().Any(s => s == string.Empty).Should().Be.False();
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Any(null));
            strings.Contains().Item("alma").Should().Be.False();
            strings.Contains().Item("cser").Should().Be.False();
            strings.Contains().Item(null).Should().Be.False();
            strings.Contains().Item(string.Empty).Should().Be.False();
            strings.Contains().One(s => s == "alma").Should().Be.False();
            strings.Contains().One(s => s.Is().StartsWith("al")).Should().Be.False();
            strings.Contains().One(s => s == "cser").Should().Be.False();
            strings.Contains().One(s => s == null).Should().Be.False();
            strings.Contains().One(s => s == string.Empty).Should().Be.False();
            strings.Contains().One("alma").Should().Be.False();
            strings.Contains().One("cser").Should().Be.False();
            strings.Contains().One(nullstring).Should().Be.False();
            Func<string, bool> nullpredicate = null;
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().One(nullpredicate));
            strings.Contains().One(string.Empty).Should().Be.False();


            strings = new List<string>() { "alma" };
            strings.Contains().Any(s => s == "alma").Should().Be.True();
            strings.Contains().Any(s => s.Is().StartsWith("al")).Should().Be.True();
            strings.Contains().Any(s => s == "cser").Should().Be.False();
            strings.Contains().Any(s => s == null).Should().Be.False();
            strings.Contains().Any(s => s == string.Empty).Should().Be.False();
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Any(null));
            strings.Contains().Item("alma").Should().Be.True();
            strings.Contains().Item("cser").Should().Be.False();
            strings.Contains().Item(null).Should().Be.False();
            strings.Contains().Item(string.Empty).Should().Be.False();
            strings.Contains().One(s => s == "alma").Should().Be.True();
            strings.Contains().One(s => s.Is().StartsWith("al")).Should().Be.True();
            strings.Contains().One(s => s == "cser").Should().Be.False();
            strings.Contains().One(s => s == null).Should().Be.False();
            strings.Contains().One(s => s == string.Empty).Should().Be.False();
            strings.Contains().One("alma").Should().Be.True();
            strings.Contains().One("cser").Should().Be.False();
            strings.Contains().One(nullstring).Should().Be.False();
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().One(nullpredicate));
            strings.Contains().One(string.Empty).Should().Be.False();

            strings = new List<string>() { "alma", "alma", "alom" };
            strings.Contains().Any(s => s == "alma").Should().Be.True();
            strings.Contains().Any(s => s.Is().StartsWith("al")).Should().Be.True();
            strings.Contains().Any(s => s == "cser").Should().Be.False();
            strings.Contains().Any(s => s == null).Should().Be.False();
            strings.Contains().Any(s => s == string.Empty).Should().Be.False();
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Any(null));
            strings.Contains().Item("alma").Should().Be.True();
            strings.Contains().Item("cser").Should().Be.False();
            strings.Contains().Item(null).Should().Be.False();
            strings.Contains().Item(string.Empty).Should().Be.False();
            strings.Contains().One(s => s == "alom").Should().Be.True();
            strings.Contains().One(s => s == "alma").Should().Be.False();
            strings.Contains().One(s => s.Is().StartsWith("alo")).Should().Be.True();
            strings.Contains().One(s => s.Is().StartsWith("al")).Should().Be.False();
            strings.Contains().One(s => s == "cser").Should().Be.False();
            strings.Contains().One(s => s == null).Should().Be.False();
            strings.Contains().One(s => s == string.Empty).Should().Be.False();
            strings.Contains().One("alma").Should().Be.False();
            strings.Contains().One("alom").Should().Be.True();
            strings.Contains().One("cser").Should().Be.False();
            strings.Contains().One(nullstring).Should().Be.False();
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().One(nullpredicate));
            strings.Contains().One(string.Empty).Should().Be.False();

            strings = new List<string>() { "alma", "alma", "alom", null };
            strings.Contains().Any(s => s == "alma").Should().Be.True();
            strings.Contains().Any(s => s.Is().StartsWith("al")).Should().Be.True();
            strings.Contains().Any(s => s == "cser").Should().Be.False();
            strings.Contains().Any(s => s == null).Should().Be.True();
            strings.Contains().Any(s => s == string.Empty).Should().Be.False();
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().Any(null));
            strings.Contains().Item("alma").Should().Be.True();
            strings.Contains().Item("cser").Should().Be.False();
            strings.Contains().Item(null).Should().Be.True();
            strings.Contains().Item(string.Empty).Should().Be.False();
            strings.Contains().One(s => s == "alom").Should().Be.True();
            strings.Contains().One(s => s == "alma").Should().Be.False();
            strings.Contains().One(s => s.Is().Not.Null() && s.Is().StartsWith("alo")).Should().Be.True();
            strings.Contains().One(s => s.Is().Not.Null() && s.Is().StartsWith("al")).Should().Be.False();
            strings.Contains().One(s => s == "cser").Should().Be.False();
            strings.Contains().One(s => s == null).Should().Be.True();
            strings.Contains().One(s => s == string.Empty).Should().Be.False();
            strings.Contains().One("alma").Should().Be.False();
            strings.Contains().One("alom").Should().Be.True();
            strings.Contains().One("cser").Should().Be.False();
            strings.Contains().One(nullstring).Should().Be.True();
            Should.Core.Assertions.Assert.Throws<ArgumentNullException>(() => strings.Contains().One(nullpredicate));
            strings.Contains().One(string.Empty).Should().Be.False();
        }

    }
}
